home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Hot Mix 17
/
Hot Mix 17.iso
/
HM17_SGI
/
research
/
lib
/
lu_complex.pro
< prev
next >
Wrap
Text File
|
1997-07-08
|
7KB
|
176 lines
;$Id: lu_complex.pro,v 1.9 1997/01/15 03:11:50 ali Exp $
;
; Copyright (c) 1994-1997, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
;+
; NAME:
; LU_COMPLEX
;
; PURPOSE:
; This function solves an N by N complex linear system using
; LU decomposition. The result is an N-element complex vector.
; Alternatively, this function computes the generalized inverse
; of an N by N complex array using LU decomposition. The result
; is an N by N complex array.
;
; CATEGORY:
; Complex Linear Algebra.
;
; CALLING SEQUENCE:
; Result = LU_COMPLEX(A, B)
;
; INPUTS:
; A: An N by N complex array.
;
; B: An N-element right-side vector (real or complex).
;
; KEYWORD PARAMETERS:
; DOUBLE: If set to a non-zero value, computations are done in
; double precision arithmetic.
;
; INVERSE: If set to a non-zero value, the generalized inverse of A
; is computed. In this case the input parameter B is ignored.
;
; SPARSE: If set to a non-zero value, the input array is converted
; to row-indexed sparse storage format. Computations are
; done using the iterative biconjugate gradient method.
; This keyword is effective only when solving complex linear
; systems. This keyword has no effect when calculating the
; generalized inverse.
;
; EXAMPLE:
; 1) Define a complex array (A) and right-side vector (B).
; A = [[complex(1, 0), complex(2,-2), complex(-3,1)], $
; [complex(1,-2), complex(2, 2), complex(1, 0)], $
; [complex(1, 1), complex(0, 1), complex(1, 5)]]
; B = [complex(1, 1), complex(3,-2), complex(1,-2)]
;
; Solve the complex linear system (Az = B) for z.
; z = LU_COMPLEX(a, b)
;
; 2) Compute the generalized inverse of A.
; inv = LU_COMPLEX(a, b, /inverse)
;
; PROCEDURE:
; LU_COMPLEX solves the complex linear system Az = b using
; LU decomposition. If the SPARSE keyword is set, the coefficient
; array is converted to row-indexed sparse storage format and the
; system is solved using the iterative biconjugate gradient method.
; LU_COMPLEX computes the generalized inverse of the complex
; array A using LU decomposition if B is supplied as an arbitrary
; scalar value or if the INVERSE keyword is set.
;
; REFERENCE:
; Numerical Recipes, The Art of Scientific Computing (Second Edition)
; Cambridge University Press
; ISBN 0-521-43108-5
;
; MODIFICATION HISTORY:
; Written by: GGS, RSI, October 1993
; Modified: GGS, RSI, February 1994
; Transposing the array prior to calling LU_COMPLEX
; is no longer necessary. LU_COMPLEX is now able to
; compute the generalized inverse of an N by N complex
; array using LU decomposition.
; Modified: GGS, RSI, June 1994
; Included support for sparse complex arrays using the
; Numerical Recipes functions NR_SPRSIN and NR_LINBCG.
; Modified: GGS, RSI, Decemberber 1994
; Added support for double-precision complex inputs.
; Reduced internal memory allocation requirements.
; Added INVERSE keyword. New documentation header.
; Modified: GGS, RSI, April 1996
; Modified keyword checking and use of double precision.
;-
FUNCTION LU_Complex, A, B, Double = Double, Inverse = Inverse, Sparse = Sparse
ON_ERROR, 2 ;Return to caller if error occurs.
if N_PARAMS() ne 2 then $
MESSAGE, "Incorrect number of input arguments."
TypeA = SIZE(A)
TypeB = SIZE(B)
if TypeA[TypeA[0]+1] ne 6 and TypeA[TypeA[0]+1] ne 9 then $
MESSAGE, "Input array must be complex or double-complex."
if TypeA[1] ne TypeA[2] then $
MESSAGE, "Input array must be square."
if TypeA[2] ne TypeB[TypeB[0]+2] and TypeB[TypeB[0]+2] ne 1 then $
MESSAGE, "Input array and right-side vector are of incompatible size."
;If the DOUBLE keyword is not set then the internal precision and
;result are determined by the type of input.
if N_ELEMENTS(Double) eq 0 then $
Double = (TypeA[TypeA[0]+1] eq 9 or TypeB[TypeB[0]+1] eq 5 or $
TypeB[TypeB[0]+1] eq 9)
;Double-precision complex.
if Double ne 0 then begin
Comp = [[DOUBLE(A), -IMAGINARY(A)], $
[IMAGINARY(A), DOUBLE(A)]]
;Generalized inverse of A (does not depend upon SPARSE keyword).
if TypeB[TypeB[0]+2] eq 1 or KEYWORD_SET(Inverse) then begin
Vec = DBLARR(2L*TypeA[1])
Inv = DCOMPLEXARR(TypeA[1], TypeA[1])
;Compute the LU decomp only once and iterate on it!
LUDC, Comp, Index, Double = Double
for k = 0, TypeA[1]-1 do begin
Vec[k] = 1.0d
Sol = LUSOL(Comp, Index, Vec, Double = Double)
Vec[k] = 0.0d
Inv[k, *] = DCOMPLEX(Sol[0:TypeA[1]-1], Sol[TypeA[1]:*])
endfor
RETURN, Inv
endif else begin ;Solve Az = b
;Rhs complex?
if TypeB[TypeB[0]+1] ne 6 and TypeB[TypeB[0]+1] ne 9 then $
Vec = [B, DBLARR(TypeB[TypeB[0]+2])] $ ;No.
else Vec = [DOUBLE(B), IMAGINARY(B)] ;Yes.
if keyword_set(SPARSE) eq 0 then begin ;Dense coefficient array.
LUDC, Comp, Index, Double = Double
Sol = LUSOL(Comp, Index, Vec, Double = Double)
endif else begin ;Sparse coefficient array.
Sol = LINBCG(SPRSIN(Comp, Double = Double), Vec, $
REPLICATE(1.0d, 2L*TypeB[TypeB[0]+2]), Double = Double)
endelse
RETURN, DCOMPLEX(Sol[0:TypeA[1]-1], Sol[TypeA[1]:*])
endelse
;Single-precision complex.
endif else begin
Comp = [[FLOAT(a), -IMAGINARY(a)], $
[IMAGINARY(a), FLOAT(a)]]
;Generalized Inverse of A (does not depend upon SPARSE keyword).
if TypeB[TypeB[0]+2] eq 1 or KEYWORD_SET(Inverse) then begin
Vec = fltarr(2L*TypeA[1])
Inv = complexarr(TypeA[1], TypeA[1])
;Compute the LU decomp only once and iterate on it!
LUDC, Comp, Index, Double = Double
for k = 0, TypeA[1]-1 do begin
Vec[k] = 1.0
Sol = LUSOL(Comp, Index, Vec, Double = Double)
Vec[k] = 0.0
Inv[k, *] = COMPLEX(Sol[0:TypeA[1]-1], Sol[TypeA[1]:*])
endfor
RETURN, Inv
endif else begin ;Solve Az = b
;Rhs complex?
if TypeB[TypeB[0]+1] ne 6 and TypeB[TypeB[0]+1] ne 9 then $
Vec = [B, FLTARR(TypeB[TypeB[0]+2])] $ ;No.
else Vec = [FLOAT(B), IMAGINARY(B)] ;Yes.
if keyword_set(SPARSE) eq 0 then begin ;Dense coefficient array.
LUDC, Comp, Index, Double = Double
Sol = LUSOL(Comp, Index, Vec, Double = Double)
endif else begin ;Sparse coefficient array.
Sol = LINBCG(SPRSIN(Comp, Double = Double), Vec, $
REPLICATE(1.0, 2L*TypeB[TypeB[0]+2]), Double = Double)
endelse
RETURN, COMPLEX(Sol[0:TypeA[1]-1], Sol[TypeA[1]:*])
endelse
endelse
END